Proba extendre esqueletonització 2
BW_prob = llistat_imatges{1};
imshow(BW_prob)
Retallem la imatge
[imageArray_cropped, BW_prob_cropped] = retallar_BWRGBimatge_BB(imageArray, BW_prob, 5);
imshowpair(imageArray_cropped, BW_ini_regio_cropped, "montage")
% Extenent el esquelet i reduint la única línea
[~, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, true, true);
imshow(sfMaskBurn_new); dades_imatge
dades_imatge = 704.1047
% Extenent esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, true, false);
imshow(sfMaskBurn_new); dades_imatge
dades_imatge = 704.1047
% sense extendre esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, false, false);
imshow(sfMaskBurn_new); dades_imatge
dades_imatge = 697.6905
Ara probarem d'extendre la punta de l'esqueletonització de forma directe amb la imatge, i no amb el punt més proper com ocórre amb cóm és definit en la funció extendre_skel() de esqueletonitzacio_josep().
Veiem la punta de la imatge
[sfMaskBurn_new_punt, xy_punta] = imcrop(imoverlay(BW_prob_cropped, BW_skel, "r")); close
imshow(sfMaskBurn_new_punt, 'InitialMagnification','fit')
Primer de tot obtenim els endpoints
endopints_BWskel = find(bwmorph(BW_skel,'endpoints'));
% Grafiquem els endpoints
[x_endpoint, y_endpoint] = ind2sub(size(BW_prob_cropped), endopints_BWskel);
imshow(imoverlay(BW_prob_cropped, BW_skel, "r" ))
hold on;
% plot(y_c, x_r, 'r-', 'LineWidth', 2);
plot(y_endpoint, x_endpoint, 'b.','markersize',14)
hold off
Obtenim l'angle
cada_val = 2
cada_val = 2
matriu_nova = BW_skel(x_endpoint-cada_val:x_endpoint+cada_val, y_endpoint-cada_val:y_endpoint+cada_val)
matriu_nova = 5×5 logical array
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
cada_val2 = cada_val-1;
[x_matnova, y_matnova] = size(matriu_nova);
matrui_nova_2 = matriu_nova;
matrui_nova_2(2:x_matnova-1,2:x_matnova-1) = 0;
matrui_nova_2_show = matrui_nova_2; matrui_nova_2_show(((x_matnova-1)/2)+1, ((y_matnova-1)/2)+1) = 1;
figure
imshowpair_d = imshowpair(matriu_nova, matrui_nova_2_show, "montage"); imshow(imshowpair_d.CData, 'InitialMagnification','fit')
clear matriu_nova
sum(matrui_nova_2(:))
ans = 1
%matriu_nova_2 = BW_skel_new(x_endpoint-cada_val2:x_endpoint+cada_val2, y_endpoint-cada_val2:y_endpoint+cada_val2)
% Obtenim l'angle
y_1 = ((y_matnova-1)/2)+1;
x_1 = ((x_matnova-1)/2)+1;
[y_2, x_2] = find(matrui_nova_2);
angle_open = abs(atand((y_2-y_1)/(x_2-x_1)))
angle_open = 45
figure
%plot([x_1, y_1], [x_2, y_2])
imshow(matrui_nova_2_show, 'InitialMagnification','fit')
hold on
line([x_1, x_2], [y_1, y_2])
hold off
Mirem com funciona la funcio extendre_line
% function [BW_skel_pixels, line_write_points_cell] = extendre_skel(BW_skel_inicial, BW_inicial)
BW_skel_inicial = BW_skel;
BW_inicial = BW_prob_cropped;
% Donada una imatge esqueletonitzada d'una imatge binaria, s'allarguen les
% puntes d'aquesta de manera que els extrems de la imatge esqueletonitzada
% inicial arriben a les bores de la superficie de la imatge binària.
% Nota: s'han tret els elements de graficació.
% Amb l'ajuda de MATLAB Answers: https://es.mathworks.com/matlabcentral/answers/1447854-convert-line-to-pixels-in-a-image-from-coordenade
% Input
% BW_skel_inicial - imatge esqueletonitzada
% BW_inicial - imatge binaria de la imatge esqueletonitzada
% Output:
% BW_skel_pixels - imatge esqueletonitzada
% Montatge_final_pixels - montatge imatge binaria i imatge esqueletonitzda
% line_write_points_cell - cell amb els dos punts en que s'allarga la imatge esqueletonitzada
% INICI FUNCIO
% Busquem punts finals
punts_ini_fini_im = bwmorph(BW_skel_inicial, 'endpoints');
[row_find, col_find] = find(punts_ini_fini_im);
% ENDPOINTS
endpoints_inifin = [row_find col_find];
% Busquem punts perimetrals
boundaries = bwboundaries(BW_inicial);
% SUPERFICIAL POINTS
superf_points = boundaries{1};
% Graficació
% visboundaries(boundaries) %|Per a visualitzar els contorns
% imshow(BW_inicial - BW_skel_inicial)
% hold on
% visboundaries(boundaries)
% hold off
% % Obtenir l'angle d'una linia:
% point1 = [22, -114];
% point2 = [693, -233];
% x1 = point1(1);
% y1 = point1(2);
% x2 = point2(1);
% y2 = point2(2);
% slope = (y2 - y1) ./ (x2 - x1)
% angle = atand(slope)
% Comparison between endpoints and superficial points
% Euclidean theory
x_var_1 = endpoints_inifin(1,1);
x_var_2 = superf_points(1,1);
y_var_1 = endpoints_inifin(1,2);
y_var_2 = superf_points(1,2);
dist_var = sqrt((x_var_2-x_var_1)^2+(y_var_2-y_var_1)^2);
% Loop euclidean
xy_coord_tot = [];
for cada_endp_skel = 1:length(endpoints_inifin)
% canviar el 1 inicial que es la liniaaa (cada punt)
minim_dist = Inf;
for cada_punt_sup = 1:length(superf_points)
x_var_1 = endpoints_inifin(cada_endp_skel,1);
x_var_2 = superf_points(cada_punt_sup,1);
y_var_1 = endpoints_inifin(cada_endp_skel,2);
y_var_2 = superf_points(cada_punt_sup,2);
dist_var = sqrt((x_var_2-x_var_1)^2+(y_var_2-y_var_1)^2);
% Si es més petit:
if minim_dist > dist_var
% Distancia
minim_dist = dist_var;
% Punt en que es troba
xy_coord = superf_points(cada_punt_sup,:);
end
end
xy_coord_tot = [xy_coord_tot; xy_coord];
end
%Graficar els punts
BW_skel_graph = imoverlay(BW_inicial, BW_skel_inicial, 'r');
imshow(BW_skel_graph);
hold on; % Prevent image from being blown away.
plot(xy_coord_tot(1,2),xy_coord_tot(1,1),'r+', 'MarkerSize', 50);
plot(xy_coord_tot(2,2),xy_coord_tot(2,1),'r+', 'MarkerSize', 50);
hold off
% Graficar linia entre els punts:
BW_skel_pixels = BW_skel_inicial;
%imshow(BW_skel_graph);
%hold on
line_write_points_cell = {};
for cada_endpoint_saps = 1:length(endpoints_inifin)
endpoint1 = endpoints_inifin(cada_endpoint_saps, :); % xy endpoint 1
suppoint1 = xy_coord_tot(cada_endpoint_saps, :);
line_write_points = [endpoint1; suppoint1];
line_write_points_cell{cada_endpoint_saps} = line_write_points;
%line(line_write_points(:, 2),line_write_points(:, 1),'Color','y','LineWidth',4)
% Fem el mateix amb la funció de generar pixels que ens ha dit l'amic
T_var=false(size(BW_inicial));
T_var(endpoint1(1), endpoint1(2))=1; %line end point 1
T_var(suppoint1(1), suppoint1(2))=1; %line end point 2
BW_skel_pixels = BW_skel_pixels|bwconvhull(T_var);
% bwconvhull el que fa es unir els pixels que hi ha en una imatge.
% D'aquesta manera, s'uneixen els dos punts (inicial i final) que hem definit.
% Llavors la línia definida es suma a la imatge esqueletotnitzada
% inicial.
% Descripció variables
%
% line_write_points <- punts de les línies
% endpoints_inifin <- punts inicial i final de la imatge esqueletonitzada
% xy_coord_tot <- punt dels punts més pròxims
% line_write_points_cell <- cell dels line_write_points
end
%hold off
% % Exportem, llegim i eliminem la imatge temporal (no ho se fer d'una altre manera)
% exportgraphics(gca, 'temporal_skel_llarg.png');
% imatge_arxi_ciru = imread("temporal_skel_llarg.png");
% delete temporal_skel_llarg.png
%
%
Montatge_final_pixels = imoverlay(BW_inicial, BW_skel_pixels, "r");
imshow(Montatge_final_pixels)
% FINAL FUNCIO
Apliquem nova extensio
% Obtenim els punts finals de l'esqueletonització, i la superfície de la
% imatge
punts_ini_fini_im = bwmorph(BW_skel_inicial, 'endpoints');
[row_find, col_find] = find(punts_ini_fini_im);
inx_endpoints = find(punts_ini_fini_im);
endpoints_inifin = [row_find col_find]; % endpoints
% Busquem punts perimetrals
[boundaries, Leing] = bwboundaries(BW_inicial); % Elapsed time is 0.010365 seconds.
% SUPERFICIAL POINTS
superf_points = boundaries{1};
% A imatge
ind = sub2ind(size(BW_inicial),superf_points(:, 1), superf_points(:, 2))
ind = 1168×1
43777 44384 44992 45599 46207 46815 47423 48031 48639 49247
BW_perimeter = false(size(BW_inicial))
BW_perimeter = 607×594 logical array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW_perimeter(ind) = true;
imshow(BW_perimeter)
Ara anem a obtenir la regió de la imatge, per a posteriorment veure quins pixels serien els que encaixarien amb l'angle
Obtenim els valors dels endpoints, de manera que serveixi per a poder graficar la regió de la imatge, i operar en aquesta.
BW_single_dist = bwdist(~BW_inicial);
imshow(BW_single_dist, [])
% Obtenim la distancia amb la superfície.
valors_endopints = BW_single_dist(inx_endpoints)
valors_endopints = 2×1 single column vector
2.0000 6.0828
% Això ens permetrà expandir la imatge amb suficiencia, sense haber
% d'operar amb tota la imatge.
[matriu_nova_X, matrui_nova_2_X, matrui_nova_2_show_X, matsort, punt_centr] = matriu_nova(BW_perimeter, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
La imatge original
imshow(matriu_nova_X)
Els contorns de la imatge original
imshow(matrui_nova_2_X)
Els contorns de la imatge original, amb el punt central marcat
imshow(matrui_nova_2_show_X)
Ara anem a veure, per a cada punt de la regió de la imatge, l'angle que es forma:
% Index de cada punt de la matriu
indx_regions_perimet = find(matriu_nova_X);
% Index del punt mig
indx_punt_mig = sub2ind(size(matriu_nova_X), punt_centr(1), punt_centr(2));
% x,y del pixel mig
x_mat_1 = punt_centr(1); y_mat_1 = punt_centr(2)
y_mat_1 = 8
for cada_indx = indx_regions_perimet'
cada_indx % Cada index de la imatge on hi ha un pixel.
% x,y de cada pixel
[y_mat_2, x_mat_2] = ind2sub(size(matriu_nova_X), cada_indx)
% Obtenim l'angle
angle_pix = abs(atand((y_mat_1 - y_mat_2)/(x_mat_1 - x_mat_2)));
% Si ho volem graficar:
figure
imshow(matriu_nova_X, 'InitialMagnification','fit')
hold on
line([x_mat_1, x_mat_2], [y_mat_1, y_mat_2])
title(strcat(string(round(angle_pix, 1)), "degree"))
hold off
end
cada_indx = 15
y_mat_2 = 15
x_mat_2 = 1
cada_indx = 30
y_mat_2 = 15
x_mat_2 = 2
cada_indx = 45
y_mat_2 = 15
x_mat_2 = 3
cada_indx = 60
y_mat_2 = 15
x_mat_2 = 4
cada_indx = 61
y_mat_2 = 1
x_mat_2 = 5
cada_indx = 75
y_mat_2 = 15
x_mat_2 = 5
cada_indx = 76
y_mat_2 = 1
x_mat_2 = 6
cada_indx = 89
y_mat_2 = 14
x_mat_2 = 6
cada_indx = 91
y_mat_2 = 1
x_mat_2 = 7
cada_indx = 104
y_mat_2 = 14
x_mat_2 = 7
cada_indx = 106
y_mat_2 = 1
x_mat_2 = 8
cada_indx = 119
y_mat_2 = 14
x_mat_2 = 8
cada_indx = 121
y_mat_2 = 1
x_mat_2 = 9
cada_indx = 133
y_mat_2 = 13
x_mat_2 = 9
cada_indx = 137
y_mat_2 = 2
x_mat_2 = 10
cada_indx = 148
y_mat_2 = 13
x_mat_2 = 10
cada_indx = 153
y_mat_2 = 3
x_mat_2 = 11
cada_indx = 163
y_mat_2 = 13
x_mat_2 = 11
cada_indx = 168
y_mat_2 = 3
x_mat_2 = 12
cada_indx = 177
y_mat_2 = 12
x_mat_2 = 12
cada_indx = 184
y_mat_2 = 4
x_mat_2 = 13
cada_indx = 191
y_mat_2 = 11
x_mat_2 = 13
cada_indx = 200
y_mat_2 = 5
x_mat_2 = 14
cada_indx = 201
y_mat_2 = 6
x_mat_2 = 14
cada_indx = 206
y_mat_2 = 11
x_mat_2 = 14
cada_indx = 217
y_mat_2 = 7
x_mat_2 = 15
cada_indx = 218
y_mat_2 = 8
x_mat_2 = 15
cada_indx = 219
y_mat_2 = 9
x_mat_2 = 15
cada_indx = 220
y_mat_2 = 10
x_mat_2 = 15
cada_indx = 221
y_mat_2 = 11
x_mat_2 = 15
Fins aqui tenim que podem passar al llarg de cada pixel de la regió, i obtenir els angles.
Ara el que necessitem és: determinar l'angle de la última regió de la imatge esqueletonitzada
Per a fer-ho, tornarem a agafar la regió de la imatge, però aquesta vegada serà la imatge esqueletonitzada, i agafarem l'angle últim que es forma, i en farem la mitja dels últims punts:
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, 4, x_endpoint(2), y_endpoint(2));
La imatge original
imshow(matriu_nova_skel, 'InitialMagnification','fit')
Els contorns de la imatge original
imshow(matrui_nova_2_skel, 'InitialMagnification','fit')
Els contorns de la imatge original, amb el punt central marcat
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
Si volem obtenir l'angle:
[y_mat_skel, x_mat_skel] = find(matrui_nova_2_skel)
y_mat_skel = 4
x_mat_skel = 1
On l'angle del punt central serà:
x_mat_centr = punt_centr_skel(1); y_mat_centr = punt_centr_skel(2);
Obtenim l'angle
% Obtenim l'angle
angle_pix = abs(atand((y_mat_centr - y_mat_skel)/(x_mat_centr - x_mat_skel)));
% Si ho volem graficar:
figure
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
hold on
line([x_mat_centr, x_mat_skel], [y_mat_centr, y_mat_skel])
title(strcat(string(round(angle_pix, 1)), "degree"))
hold off
Ara fem això per a cada pixel de la imatge esqueletonitzada, fins a un límit. ççç optimitzar fins a certa variació de percentatge de canvi del angle.
angle_pix_mean = [];
for cada_n_pixel = 1:10
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, cada_n_pixel, x_endpoint(2), y_endpoint(2));
%La imatge original
%imshow(matriu_nova_skel, 'InitialMagnification','fit')
%Els contorns de la imatge original
%imshow(matrui_nova_2_skel, 'InitialMagnification','fit')
%Els contorns de la imatge original, amb el punt central marcat
%imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
%Si volem obtenir l'angle:
[y_mat_skel, x_mat_skel] = find(matrui_nova_2_skel);
%On l'angle del punt central serà:
x_mat_centr = punt_centr_skel(1); y_mat_centr = punt_centr_skel(2);
%Obtenim l'angle
% Obtenim l'angle
angle_pix = abs(atand((y_mat_centr - y_mat_skel)/(x_mat_centr - x_mat_skel)));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean)
angle_pix_mean = angle_pix;
else
angle_pix_mean(end+1) = angle_pix;
end
% Si ho volem graficar:
figure
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
hold on
line([x_mat_centr, x_mat_skel], [y_mat_centr, y_mat_skel])
title(strcat(string(round(angle_pix, 1)), "degree"))
hold off
end
Veiem en la variable angle_pix_mean els diferents angles, al llarg de cada pixel:
angle_pix_mean
angle_pix_mean = 1×10
45.0000 26.5651 18.4349 14.0362 11.3099 0 0 7.1250 6.3402 5.7106
BW_skel_regio = BW_skel(matsort_skel(1):matsort_skel(2), matsort_skel(3):matsort_skel(4));
imshow(BW_skel_regio, 'InitialMagnification','fit')
% PROBA
[y_fins_regio, x_finds_regio] = find(BW_skel_regio)
y_fins_regio = 11×1
10 10 10 11 11 10 10 10 10 10
x_finds_regio = 11×1
1 2 3 4 5 6 7 8 9 10
imshow(BW_skel_regio, 'InitialMagnification','fit')
hold on
for n_cada_angl = 1:length(angle_pix_mean)
cada_angl = angle_pix_mean(end - n_cada_angl +1);
line([x_mat_centr, x_finds_regio(n_cada_angl)], [y_mat_centr, y_fins_regio(n_cada_angl)]);
text(x_finds_regio(n_cada_angl), y_fins_regio(n_cada_angl), string(round(cada_angl, 1)));
end
hold off
Veiem que fixar-nos amb un sol punt no és llògic, o si més no, fixar cada angle amb el punt final.
El que seria més llogic seria veure en quin punt de la imatge perimetral la suma de la diferència entre els angles és més propera a zero.
exemple 2:
I cóm es fa això?
Bé...
bulma3.gif
Anem-ho a veure.
El que hem de fer és, per a cada píxel de la regió de la imatge primetral, obtenir l'angle que hi ha per a cada píxel de la regió de la imatge esqueletonitzada.
Llavors,
primer de tot, tenim la imatge perimetral, d'un endpoint en concret:
[matriu_nova_perimetral, matrui_nova_2_perimetral, matrui_nova_2_show_perimetral, matsort_perimetral, punt_centr_perimetral] = matriu_nova(BW_perimeter, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
imshow(matriu_nova_perimetral, 'InitialMagnification','fit')
El mateix, amb la imatge esqueletonitzada
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
imshow(matriu_nova_skel, 'InitialMagnification','fit')
Molt bé, ara hem d'agafar cada píxel, de la imatge perimetral. Agafem en coordenades x i y, per a poder fer l'angle millor (en comptes de index):
[x_perim, y_perim] = find(matriu_nova_perimetral);
El nombre de píxels de la imatge ha de correspondre a la llargada obtinguda del find()
sum(matriu_nova_perimetral(:))
ans = 30
length(x_perim)
ans = 30
Fem el mateix amb els pixels de la imatge esqueletonitzada.
[x_skel, y_skel] = find(matriu_nova_skel);
En aquest cas la llargada és de 8.
Bé.
Els pixels es juntaràn en funció a aquell que els angles finals de la cua siguin menors.
Això vol dir que em de guardar d'alguna manera els angles, i veure'n l'error, per mitjà de la desviació típica, per exemple.
Ara farem la proba per 1 pixel de la imatge perimetral, i després ho exportarem a cada pixel.
% On guardarem els angles:
angle_pix_mean_proba = [];
% Ho grafiquem alhora
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
% Obtenim l'angle
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(1))/(x_skel(n_pixel_skel) - x_perim(1))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
else
angle_pix_mean_proba(end+1) = angle_pix;
end
% grafiquem
line([y_perim(1), y_skel(n_pixel_skel)], [x_perim(1), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
end
hold off
Bieen!
Ara anem a veure l'error que hi ha entre els angles.
angle_pix_mean_proba
angle_pix_mean_proba = 1×8
0 8.1301 14.0362 20.5560 26.5651 32.0054 36.8699 45.0000
mean(angle_pix_mean_proba)
ans = 22.8953
std(angle_pix_mean_proba)
ans = 15.1494
Veiem que hi ha molta variació.
Ara anem a fer el mateix per a cada angle
% Llista on guardem els angles (opcional)
angles_llista_cell = {};
% Guardem la desviació estándard, per a veure quina és la menor.
std_lower = Inf;
for n_pixel_perim = 1:length(y_perim)
% On guardarem els angles:
angle_pix_mean_proba = [];
% Ho grafiquem alhora
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
figure
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
% Obtenim l'angle
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(n_pixel_perim))/(x_skel(n_pixel_skel) - x_perim(n_pixel_perim))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
else
angle_pix_mean_proba(end+1) = angle_pix;
end
% grafiquem
line([y_perim(n_pixel_perim), y_skel(n_pixel_skel)], [x_perim(n_pixel_perim), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
end
hold off
% Guardem en
angles_llista_cell{end+1} = angle_pix_mean_proba;
% mostrem el sd i mean
mean(angle_pix_mean_proba)
std(angle_pix_mean_proba)
% Si la desviació estándard és menor:
if std(angle_pix_mean_proba) < std_lower;
std_lower = std(angle_pix_mean_proba);
% Guardem la posicio (per graficar a posteriori)
punt_minor = n_pixel_perim;
% Guardem el punt on l'angle té una sd menor
punt_final_menorangl = [x_perim(n_pixel_perim), y_perim(n_pixel_perim)];
disp("THE MINIMAL")
end
end
ans = 22.8953
ans = 15.1494
THE MINIMAL
ans = 18.6274
ans = 13.8312
THE MINIMAL
ans = 15.9869
ans = 11.4309
THE MINIMAL
ans = 14.7164
ans = 9.7520
THE MINIMAL
ans = 16.4921
ans = 9.5914
THE MINIMAL
ans = 14.8081
ans = 10.0174
ans = 18.1441
ans = 11.9098
ans = 18.4168
ans = 13.4724
ans = 21.5527
ans = 14.7912
ans = 21.4109
ans = 15.9235
ans = 26.6949
ans = 16.1560
ans = 25.8694
ans = 17.3931
ans = 33.1800
ans = 14.4256
ans = 35.9078
ans = 16.6155
ans = 43.3944
ans = 13.2709
ans = 41.9001
ans = 14.1346
ans = 53.9605
ans = 11.2724
ans = 47.0461
ans = 11.9402
ans = 58.1286
ans = 9.3119
THE MINIMAL
ans = 56.4765
ans = 9.6360
ans = 67.1835
ans = 7.1130
THE MINIMAL
ans = 65.4976
ans = 7.1767
ans = 75.2849
ans = 5.0940
THE MINIMAL
ans = 81.3570
ans = 4.2245
THE MINIMAL
ans = 68.0434
ans = 6.0252
ans = 87.9232
ans = 3.1084
THE MINIMAL
ans = 86.3583
ans = 3.0973
THE MINIMAL
ans = 80.7179
ans = 3.5959
ans = 75.2746
ans = 4.3613
ans = 70.1206
ans = 5.1572
Grafiquem aquesta
% Ho grafiquem alhora
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
figure
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
% Obtenim l'angle
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(punt_minor))/(x_skel(n_pixel_skel) - x_perim(punt_minor))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
else
angle_pix_mean_proba(end+1) = angle_pix;
end
% grafiquem
line([y_perim(punt_minor), y_skel(n_pixel_skel)], [x_perim(punt_minor), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
end
hold off
std(angle_pix_mean_proba)
ans = 9.3380
Finalment, tenim el punt on l'angle és menor.
Podem ara graficar aquest amb el endpoint, de manera que obtinguem una línia, la qual juntarem amb la imatge inicial.
% Fem imatge de zeros
matriu_punts_fin = false(size(matriu_nova_perimetral));
% Apliquem els punts:
matriu_punts_fin(punt_final_menorangl(1), punt_final_menorangl(2)) = true;
matriu_punts_fin(punt_centr_perimetral(1), punt_centr_perimetral(2)) = true;
imshow(matriu_punts_fin, 'InitialMagnification','fit')
% Ara, dels dos punts fem una linia
matriu_punts_linia = bwconvhull(matriu_punts_fin);
imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Si volguéssim, ho podem graficar a la principal
matriu_nova_graficar_fin = matriu_nova_graficar;
matriu_nova_graficar_fin = matriu_nova_graficar_fin|matriu_punts_linia;
imshow(matriu_nova_graficar_fin, 'InitialMagnification','fit')
imshow(imoverlay(matriu_nova_graficar_fin, matriu_punts_linia, "r"), 'InitialMagnification','fit')
Bueeno,
ara ho hem de passar a la imatge principal,
i després farem el mateix, per a cada endpoint. :)
Ho escalem a la imatge original:
Tenim els punts, els cuals guardarem com posicions, i no com imatge, per tal d'optimitzar la imatge. Lo complicat serà veure com passem de la matriu (imatge) petita, a la gran.
imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Busquem els punts
[y_linia, x_linia] = find(matriu_punts_linia)
y_linia = 8×1
8 8 8 8 8 8 8 8
x_linia = 8×1
8 9 10 11 12 13 14 15
Quan habiem obtingut la imatge, habiem guardat les coordenades de la mateixa en la seva obtenció:
matsort_perimetral
matsort_perimetral = 1×4
517 531 507 521
Això significava que si feiem un BW(x1:x2, y1:y2) amb aquestes regións, obteniem la imatge.
Suposem que són x1, x2, y1, y2:
Si suméssim a les línies:
BW_perimeter_proba = BW_perimeter;
imshow(BW_perimeter_proba)
% Definim els punts x i y
x_linia_escalatBW = x_linia + matsort_perimetral(3)-1;
y_linia_escalatBW = y_linia + matsort_perimetral(1)-1;
BW_perimeter_proba(y_linia_escalatBW, x_linia_escalatBW) = true;
imshow(BW_perimeter_proba)
% Grafiquem
BW_perimeter_proba_2 = false(size(BW_perimeter_proba));
BW_perimeter_proba_2(y_linia_escalatBW, x_linia_escalatBW) = true;
imshow(imoverlay(BW_skel|BW_perimeter, BW_perimeter_proba_2, "r"))
Ara haurem d'aplicar això en una forma compilada, de manera que esdevingui una sola funció.
Donada una imatge binària, i la seva esqueletonització, el que s'hauria d'obtenir és l'esqueletonització allargada d'aquesta, simplement, per a cada un dels seus endpoints.
% Variables
%
% Input
% BW_inicial : Imatge binaria inicial
% BW_skel : Imatge esqueletonitzada inicial
%
% Output
% BW_skel_final_estes : imatge esqueletonitzada final
%
% ÇÇÇ fer que nomes es detecti un objecte. El mes gran si n'hi ha mes d'un.
%imshow(imoverlay(BW_inicial, BW_skel, "r"), 'InitialMagnification','fit')
% _Obtenció dels endpoints_
% x,y
[x_endpoint, y_endpoint] = find(bwmorph(BW_skel, 'endpoints'));
% index
inx_endpoints = find(bwmorph(BW_skel,'endpoints'));
% Valors de distancia en els endpoints
BW_single_dist = bwdist(~BW_inicial);
%imshow(BW_single_dist, [])
valors_endopints = BW_single_dist(inx_endpoints)
valors_endopints = 2×1 single column vector
1.0000 7.0711
% % Grafiquem els endpoints
% imshow(imoverlay(BW_prob_cropped, BW_skel, "r" ))
% hold on;
% plot(row_find, row_find, 'b.','markersize',14)
% hold off
% _Obtenció imatge perimetral_
% Busquem punts perimetrals
[boundaries, Leing] = bwboundaries(BW_inicial); % Elapsed time is 0.010365 seconds.
% Superficial points
superf_points = boundaries{1};
% A imatge
ind = sub2ind(size(BW_inicial),superf_points(:, 1), superf_points(:, 2))
ind = 1147×1
29630 30036 30035 30441 30440 30846 30845 31251 31657 32063
BW_perimeter = false(size(BW_inicial))
BW_perimeter = 407×692 logical array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW_perimeter(ind) = true;
imshow(BW_perimeter)
% La imatge binaria esqueltonitzada final:
BW_skel_final_estes = BW_skel;
% _Per cada endpoint_
for n_endpoint = 1:length(x_endpoint)
% Si el endpoint està tocant al perímetre
if BW_perimeter(x_endpoint(n_endpoint), y_endpoint(n_endpoint))
% % Grafiquem
%imshow(BW_perimeter); hold on
%plot(y_endpoint(1), x_endpoint(1), 'b.','markersize',14); hold off
%BW_perimeter(x_endpoint(1), y_endpoint(1))
%imshow(BW_skel); hold on
%plot(y_endpoint(1), x_endpoint(1), 'b.','markersize',14); hold off
%BW_skel(x_endpoint(1), y_endpoint(1))
%imshow(imoverlay(BW_perimeter, BW_skel, "r"))
continue
end
% _Obtenció de les matrius_
% Matriu BW perimetral
[matriu_nova_perimetral, matrui_nova_2_perimetral, matrui_nova_2_show_perimetral, matsort_perimetral, punt_centr_perimetral] = matriu_nova(BW_perimeter, round(double(valors_endopints(n_endpoint)))+1, x_endpoint(n_endpoint), y_endpoint(n_endpoint));
imshow(matriu_nova_perimetral, 'InitialMagnification','fit')
%El mateix, amb la imatge esqueletonitzada
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, round(double(valors_endopints(n_endpoint)))+1, x_endpoint(n_endpoint), y_endpoint(n_endpoint));
imshow(matriu_nova_skel, 'InitialMagnification','fit')
imshow(imoverlay(matriu_nova_perimetral, matriu_nova_skel, "r"))
% Possible filtre: bwconncomp(matriu_nova_perimetral|matriu_nova_perimetral, 4)
% __Tractament amb matrius__
% _Obtenció dels punts_
[x_perim, y_perim] = find(matriu_nova_perimetral);
% Fem el mateix amb els pixels de la imatge esqueletonitzada.
[x_skel, y_skel] = find(matriu_nova_skel);
% _Determinació angles_
% Llista on guardem els angles (opcional)
angles_llista_cell = {};
% Guardem la desviació estándard, per a veure quina és la menor.
std_lower = Inf;
for n_pixel_perim = 1:length(y_perim)
% On guardarem els angles:
angle_pix_mean_proba = [];
%Ho grafiquem alhora
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
figure
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
% Obtenim l'angle
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(n_pixel_perim))/(x_skel(n_pixel_skel) - x_perim(n_pixel_perim))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
else
angle_pix_mean_proba(end+1) = angle_pix;
end
%% grafiquem
%line([y_perim(n_pixel_perim), y_skel(n_pixel_skel)], [x_perim(n_pixel_perim), x_skel(n_pixel_skel)]);
%text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
end
%hold off
% Guardem en
angles_llista_cell{end+1} = angle_pix_mean_proba; % ÇÇÇ potser no cal
% %mostrem el sd i mean
%mean(angle_pix_mean_proba)
%std(angle_pix_mean_proba)
% Si la desviació estándard és menor:
if std(angle_pix_mean_proba) < std_lower;
std_lower = std(angle_pix_mean_proba);
% Guardem la posicio (per graficar a posteriori)
punt_minor = n_pixel_perim;
% Guardem el punt on l'angle té una sd menor
punt_final_menorangl = [x_perim(n_pixel_perim), y_perim(n_pixel_perim)];
%disp("THE MINIMAL")
end
end
% __Graficació de la regió__
% Ho grafiquem alhora
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
figure; imshow(matriu_nova_graficar, 'InitialMagnification','fit'); hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
% Obtenim l'angle
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(punt_minor))/(x_skel(n_pixel_skel) - x_perim(punt_minor))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba); angle_pix_mean_proba = angle_pix;
else; angle_pix_mean_proba(end+1) = angle_pix; end
% grafiquem
line([y_perim(punt_minor), y_skel(n_pixel_skel)], [x_perim(punt_minor), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
end; hold off
% _Obtenció en imatge_
% Fem imatge de zeros
matriu_punts_fin = false(size(matriu_nova_perimetral));
% Apliquem els punts:
matriu_punts_fin(punt_final_menorangl(1), punt_final_menorangl(2)) = true;
matriu_punts_fin(punt_centr_perimetral(1), punt_centr_perimetral(2)) = true;
figure; imshow(matriu_punts_fin, 'InitialMagnification','fit')
% Ara, dels dos punts fem una linia
matriu_punts_linia = bwconvhull(matriu_punts_fin);
figure; imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Si volguéssim, ho podem graficar a la principal
matriu_nova_graficar_fin = matriu_nova_graficar;
matriu_nova_graficar_fin = matriu_nova_graficar_fin|matriu_punts_linia;
figure; imshow(matriu_nova_graficar_fin, 'InitialMagnification','fit')
figure; imshow(imoverlay(matriu_nova_graficar_fin, matriu_punts_linia, "r"), 'InitialMagnification','fit')
%ara ho hem de passar a la imatge principal,
% Ho escalem a la imatge original:
% Tenim els punts, els cuals guardarem com posicions, i no com imatge, per tal d'optimitzar la imatge. Lo complicat serà veure com passem de la matriu (imatge) petita, a la gran.
figure; imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Busquem els punts
[y_linia, x_linia] = find(matriu_punts_linia)
% Quan habiem obtingut la imatge, habiem guardat les coordenades de la mateixa en la seva obtenció:
matsort_perimetral
% Això significava que si feiem un BW(x1:x2, y1:y2) amb aquestes regións, obteniem la imatge.
% Suposem que són x1, x2, y1, y2:
% Si suméssim a les línies:
BW_perimeter_proba = BW_perimeter;
figure; imshow(BW_perimeter_proba)
% Definim els punts x i y
x_linia_escalatBW = x_linia + matsort_perimetral(3)-1;
y_linia_escalatBW = y_linia + matsort_perimetral(1)-1;
% Grafiquem BW_skel amb la regió, obtenint BW_skel_final_estes.
ind_linia_escalatBW = sub2ind(size(BW_skel_final_estes), y_linia_escalatBW, x_linia_escalatBW);
BW_skel_final_estes(ind_linia_escalatBW) = true;
figure; imshow(BW_skel_final_estes)
end
y_linia = 2×1
2 3
x_linia = 2×1
2 3
matsort_perimetral = 1×4
332 336 73 77
y_linia = 8×1
9 7 8 6 5 3 4 2
x_linia = 8×1
9 10 10 11 12 13 13 14
matsort_perimetral = 1×4
72 88 604 620
figure; imshow(imoverlay(BW_skel|BW_perimeter, (BW_skel_final_estes - BW_skel)>0, "r"))
figure; imshow(imoverlay(BW_inicial, BW_skel_final_estes, "r"))
Ús de la funció
[BW_skel_final_estes] = extendre_skel_estes(BW_inicial, BW_skel);
imshow(imoverlay(BW_inicial, BW_skel_final_estes, "r"))
Ha funcionat!
bulma-dragon-ball.gif
Ara probarem al llarg de varies imatges
for cada_llist_img = 1:length(llistat_imatges)
BW_inicial = llistat_imatges{cada_llist_img};
%imshow(BW_inicial)
% Retallem
[~, BW_inicial] = retallar_BWRGBimatge_BB(imageArray, BW_inicial, 5);
BW_skel = bwskel(BW_inicial);
[BW_skel_final_estes] = extendre_skel_estes(BW_inicial, BW_skel);
figure; imshowpair(imoverlay(BW_inicial, BW_skel_final_estes, "r"), imoverlay(BW_inicial, BW_skel, "r"), "montage")
end
Comparació extendre sense, antic i actual
for cada_llist_img = 1:length(llistat_imatges)
BW_inicial = llistat_imatges{cada_llist_img};
%imshow(BW_inicial)
% Retallem
[imageArray_cropped, BW_inicial] = retallar_BWRGBimatge_BB(imageArray, BW_inicial, 5);
BW_skel = bwskel(BW_inicial);
% Extenem, o no, esquelet
% Extenent el esquelet i reduint la única línea
[~, sfMaskBurn_new, dades_imatge_sk1] = esqueletonitzacio_josep(BW_inicial, imageArray_cropped, 1, true, true);
figure; imshow(sfMaskBurn_new); dades_imatge_sk1
% sense extendre esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge_sk2] = esqueletonitzacio_josep(BW_inicial, imageArray_cropped, 1, false, false);
figure; imshow(sfMaskBurn_new); dades_imatge_sk2
disp(strcat("Variació del ", string(((dades_imatge_sk1 -dades_imatge_sk2)/dades_imatge_sk1)*100), "%"))
end
dades_imatge_sk1 = 707.5189
dades_imatge_sk2 = 697.6905
Variació del 1.3891%
dades_imatge_sk1 = 662.8255
dades_imatge_sk2 = 653.7544
Variació del 1.3685%
dades_imatge_sk1 = 185
dades_imatge_sk2 = 153
Variació del 17.2973%